0043. 字符串相乘【中等】
1. 📝 题目描述
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
示例 1:
txt
输入: num1 = "2", num2 = "3"
输出: "6"1
2
2
示例 2:
txt
输入: num1 = "123", num2 = "456"
输出: "56088"1
2
2
提示:
1 <= num1.length, num2.length <= 200num1和num2只能由数字组成。num1和num2都不包含任何前导零,除了数字 0 本身。
2. 🎯 s.1 - 竖式乘法模拟
c
char* multiply(char* num1, char* num2) {
int m = strlen(num1), n = strlen(num2);
int len = m + n;
int* pos = (int*)calloc(len, sizeof(int));
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
int mul = (num1[i] - '0') * (num2[j] - '0');
int p1 = i + j, p2 = i + j + 1;
int sum = mul + pos[p2];
pos[p2] = sum % 10;
pos[p1] += sum / 10;
}
}
char* res = (char*)malloc((len + 1) * sizeof(char));
int start = 0;
while (start < len - 1 && pos[start] == 0) start++; // 跳过前导零
int idx = 0;
for (int i = start; i < len; i++) {
res[idx++] = '0' + pos[i];
}
res[idx] = '\0';
free(pos);
return res;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
js
/**
* @param {string} num1
* @param {string} num2
* @return {string}
*/
var multiply = function (num1, num2) {
const m = num1.length,
n = num2.length
const pos = new Array(m + n).fill(0)
for (let i = m - 1; i >= 0; i--) {
for (let j = n - 1; j >= 0; j--) {
const mul = (num1[i] - '0') * (num2[j] - '0')
const p1 = i + j,
p2 = i + j + 1
const sum = mul + pos[p2]
pos[p2] = sum % 10
pos[p1] += Math.floor(sum / 10)
}
}
const res = pos.join('').replace(/^0+/, '')
return res || '0'
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
py
class Solution:
def multiply(self, num1: str, num2: str) -> str:
m, n = len(num1), len(num2)
pos = [0] * (m + n)
for i in range(m - 1, -1, -1):
for j in range(n - 1, -1, -1):
mul = int(num1[i]) * int(num2[j])
p1, p2 = i + j, i + j + 1
total = mul + pos[p2]
pos[p2] = total % 10
pos[p1] += total // 10
res = ''.join(map(str, pos)).lstrip('0')
return res or '0'1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 时间复杂度:
,其中 和 分别是num1和num2的长度 - 空间复杂度:
,结果数组长度最多为
算法思路:
- 模拟竖式乘法:
num1[i]与num2[j]相乘的结果,进位影响pos[i+j],个位存入pos[i+j+1] - 用长度为
的整数数组pos累加每一位的贡献,最后将各位合并为字符串 - 跳过结果字符串的前导零,若全为零则返回
"0"
2.1. 数学层面:证明 pos 长度 m + n 足够存储结果
一个 m 位数最大为 m = 3,3 位数最大是 999),因此:
两数相乘:
而
pos 数组有 m + n 个位置(下标 0 到 m+n-1),恰好能容纳最多 m+n 位的结果。